package resources;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import javax.imageio.ImageIO;

import utils.MyException;

public class ResMgr {

	private static ResMgr mgr = null;
	private static String RES_DEFAULT_DIR = "res";

	private static Class<? extends Res>[] resTypes = new Class[]
	{ Sprite.class };
	private ArrayList<Res> resources = new ArrayList<Res>();

	public static ResMgr get() {
		if (mgr == null)
			mgr = new ResMgr();
		return mgr;
	}

	public void open(String name) throws MyException {
		String fileName = RES_DEFAULT_DIR;
		if (name != null)
			fileName += System.getProperty("file.separator") + name.replaceAll("\\.", System.getProperty("file.separator"));
		File root = new File(fileName);
		if (root.isDirectory() || !root.exists())
			for (File file : Files.getFilesUnder(root))
				load(file);
		else if (root.isFile())
			load(root);
	}

	public void openAll() throws MyException {
		open(null);
	}

	private void load(File file) throws MyException {
		String name = Files.getPureName(file);
		Res r;
		// already exists
		try {
			r = (Res) get(name);
			r.read(file);
		}
		// doesn't exist
		catch (MyException e) {
			for (Class<? extends Res> resType : resTypes) {
				try {
					r = resType.newInstance();
					try {
						r.read(file);
						r.setName(name);
						resources.add(r);
						// successfully read
						break;
					} catch (IOException e1) {
						// can't be read just
						continue;
					}
				} catch (InstantiationException e2) {
					e2.printStackTrace();
				} catch (IllegalAccessException e2) {
					e2.printStackTrace();
				}
			}
		}
		// exists but can't be added to its peers as it has a different type
		catch (IOException e) {
			throw new MyException("Resourced", MyException.DUPLICATE_WITH_DIFF_TYPE, name);
		}
	}

	public void close(String name) {
		for (Res res : resources)
			if (res.getName().equals(name))
				resources.remove(res);
	}

	public void closeAll() {
		resources.clear();
	}

	public ResRO get(String name) throws MyException {
		for (Res res : resources)
			if (res.getName().equals(name)) {
				return res;
			}
		throw new MyException("Resourced", MyException.NOT_FOUND_NOT_OPEN, name);
	}

	public ArrayList<String> getOpenResNames() {
		ArrayList<String> out = new ArrayList<String>();
		for (Res r : resources)
			out.add(r.getName());
		return out;
	}
}
